#ifndef BUILDINGDRAWER_H_
#define BUILDINGDRAWER_H_

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <pcl/point_types.h>

class BuildingDrawer
{
public:
	cv::Mat* image;

	BuildingDrawer(cv::Mat* _image)
	{
		image=_image;
	}

	BuildingDrawer(pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud, float res)
	{
		_pointcloud = pointcloud;

		createBitmap(res);
	}

	~BuildingDrawer()
	{
		delete image;
		image=0;
		//_pointcloud->clear();

		for(int i=0;i<_vertices.size();i++)
			delete _vertices[i];

		_vertices.clear();	
	}

	void start()
	{		

		const char* name = "Building Drawer";

		cv::namedWindow(name, CV_WINDOW_AUTOSIZE);
		
		// Set up the callback
		cvSetMouseCallback(name, &BuildingDrawer::mouseCallback,this);

		imshow( name, *image );

		cv::waitKey();

	}


	static void mouseCallback(int event, int x, int y, int flags, void* param) 
	{
		BuildingDrawer* t = static_cast<BuildingDrawer*>(param);
		//std::cout<<"V2:: "<<&t->f<<endl;
		static_cast<BuildingDrawer*>(param)->getPixelColor(event, x, y, flags,param);		
	}
	
	void getPixelColor(int event, int x, int y, int flags, void* param) {
		switch( event ){
			case CV_EVENT_MOUSEMOVE: 
				
				break;

			case CV_EVENT_LBUTTONDOWN:

				break;

			case CV_EVENT_LBUTTONUP:
				addPoint(x,y);

				break;
		}

	}

	void addPoint(int x,int y){
		
		cv::Point2i* po = new cv::Point2i(x,y);
		const char* name = "Building Drawer";
		int thickness = -1;
		 int lineType = 8;

		 cv::circle(*image,cv::Point(x,y),3,
         cv::Scalar( 255, 0, 0 ),
         thickness,
         lineType );
		 imshow( name, *image );
		 _vertices.push_back(po);
		std::cout<<"clicked: x "<<x<<", y: "<<y<<std::endl;
	}
	
	std::vector< cv::Point2i* > getVertices()
	{ return _vertices; }

private:

	void createBitmap(float _image_resolution)
	{

		Eigen::Vector4f min_p, max_p;
		pcl::getMinMax3D(*_pointcloud,min_p,max_p);

		image = new cv::Mat( cv::Mat::zeros( ((max_p.y()-min_p.y()) / _image_resolution) + 1, ((max_p.x()-min_p.x()) / _image_resolution) + 1, CV_8UC1) );
		for(int i=0;i<_pointcloud->points.size();i++)
		{

		int row = (int)( (image->rows -1) - (_pointcloud->points[i].y / max_p.y() * (image->rows-1)));
		int col = (int)(_pointcloud->points[i].x / max_p.x() * (image->cols-1));

		if(row>=image->rows || col >= image->cols || row<0 || col < 0)
			std::cout<<"OhOh -- Row: "<<row<<","<<"Col: "<<col<<","<<_pointcloud->points[i].x<<","<<_pointcloud->points[i].y<<std::endl;
		else
			image->at<uchar>( row, col ) = 0xff;
		}
		
	}

	std::vector< cv::Point2i* > _vertices;
	
	pcl::PointCloud<pcl::PointXYZ>::Ptr _pointcloud;


	
};


#endif